package errors

import (
	"errors"
	"fmt"
	"net/http"

	"gorm.io/gorm"
)

// 预定义错误类型
var (
	ErrNotFound          = errors.New("resource not found")
	ErrInvalidInput      = errors.New("invalid input")
	ErrUnauthorized      = errors.New("unauthorized access")
	ErrForbidden         = errors.New("forbidden access")
	ErrInternalServer    = errors.New("internal server error")
	ErrDuplicateEntry    = errors.New("duplicate entry")
	ErrValidation        = errors.New("validation failed")
	ErrDatabaseOperation = errors.New("database operation failed")
)

// AppError 应用错误结构
type AppError struct {
	Err        error  // 原始错误
	Message    string // 用户友好的错误消息
	StatusCode int    // HTTP状态码
	ErrorCode  string // 应用内部错误码
}

// Error 实现error接口
func (e *AppError) Error() string {
	if e.Err != nil {
		return fmt.Sprintf("%s: %v", e.Message, e.Err)
	}
	return e.Message
}

// Unwrap 支持errors.Is和errors.As
func (e *AppError) Unwrap() error {
	return e.Err
}

// NewAppError 创建新的应用错误
func NewAppError(err error, message string, statusCode int, errorCode string) *AppError {
	return &AppError{
		Err:        err,
		Message:    message,
		StatusCode: statusCode,
		ErrorCode:  errorCode,
	}
}

// 常用错误创建函数
func NewNotFoundError(message string, err error) *AppError {
	return NewAppError(err, message, http.StatusNotFound, "NOT_FOUND")
}

func NewBadRequestError(message string, err error) *AppError {
	return NewAppError(err, message, http.StatusBadRequest, "BAD_REQUEST")
}

func NewUnauthorizedError(message string, err error) *AppError {
	return NewAppError(err, message, http.StatusUnauthorized, "UNAUTHORIZED")
}

func NewForbiddenError(message string, err error) *AppError {
	return NewAppError(err, message, http.StatusForbidden, "FORBIDDEN")
}

func NewInternalServerError(message string, err error) *AppError {
	return NewAppError(err, message, http.StatusInternalServerError, "INTERNAL_SERVER_ERROR")
}

func NewValidationError(message string, err error) *AppError {
	return NewAppError(err, message, http.StatusBadRequest, "VALIDATION_ERROR")
}

func NewDuplicateEntryError(message string, err error) *AppError {
	return NewAppError(err, message, http.StatusConflict, "DUPLICATE_ENTRY")
}

// IsNotFound 检查错误是否为NotFound类型
func IsNotFound(err error) bool {
	return errors.Is(err, ErrNotFound)
}

// IsDuplicateEntry 检查错误是否为DuplicateEntry类型
func IsDuplicateEntry(err error) bool {
	return errors.Is(err, ErrDuplicateEntry)
}

// IsValidationError 检查错误是否为ValidationError类型
func IsValidationError(err error) bool {
	return errors.Is(err, ErrValidation)
}

// 从GORM错误转换为应用错误
func FromGormError(err error) error {
	if err == nil {
		return nil
	}

	// 检查是否为记录未找到错误
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return ErrNotFound
	}
	
	// 默认为数据库操作错误
	return ErrDatabaseOperation
}
